import { defineStore } from 'pinia';
import { getCache, removeCache, setCache } from '@/utils/cache';
import { TOKEN_KEY, USER_INFO_KEY } from '@/enums/cacheEnum';
import { login } from '@/services/api/auth';
import { logout, refreshToken } from '@/services/api/auth';
import { LoginModel, LoginParamModel } from '@/services/model/loginModel';
import { UserInfoModel } from '@/services/model/userModel';
import { isEmpty, isUnDef } from '@/utils/is';
import { API } from '@/services/model/baseModel';
import { HttpResponse } from 'luch-request';

interface AuthState {
  token?: string;
  userInfo?: UserInfoModel;
}

export const useAuthStore = defineStore({
  id: 'auth',
  state: (): AuthState => {
    return {
      token: getCache<string>(TOKEN_KEY),
      userInfo: undefined,
    };
  },
  getters: {
    getToken: (state) => {
      const token = getCache<string>(TOKEN_KEY);
      if (isUnDef(token)) {
        return state.token;
      }
      return token;
    },
    getUserInfo: (state) => {
      const user = getCache<UserInfoModel>(USER_INFO_KEY);
      if (isUnDef(user)) {
        return state.userInfo;
      }
      return user;
    },
    isLogin: (state): boolean => {
      if (isEmpty(state.token)) {
        const token = getCache<string>(TOKEN_KEY);
        return !!token;
      }
      return !!state.token;
    },
  },
  actions: {
    initToken() {
      this.token = getCache<string>(TOKEN_KEY) || undefined;
    },
    setToken(token: string | undefined) {
      setCache(TOKEN_KEY, token);
      this.token = token;
    },
    setUserInfo(user: UserInfoModel | undefined) {
      setCache(USER_INFO_KEY, user);
      this.userInfo = user;
    },
    removeToken() {
      removeCache(TOKEN_KEY);
      removeCache(USER_INFO_KEY);
      this.setToken(undefined);
      this.setUserInfo(undefined);
    },
    /**
     * @description 登录
     */
    async login(params: LoginParamModel): Promise<HttpResponse<API<LoginModel>>> {
      try {
        this.removeToken();
        const res = await login(params);
        const { data } = res.data;
        this.setToken(data.token);
        this.setUserInfo(data.sysUser);
        return Promise.resolve(res);
      } catch (err: any) {
        return Promise.reject(err);
      }
    },
    /**
     * @description 登出
     */
    async loginOut(): Promise<any> {
      try {
        const res = await logout();
        this.removeToken();
        return Promise.resolve(res);
      } catch (err: any) {
        return Promise.reject(err);
      }
    },
    /**
     * @description 刷新token
     */
    async refreshToken(): Promise<LoginModel> {
      try {
        const { data } = await refreshToken();
        this.setToken(data.data.token);
        return Promise.resolve(data.data);
      } catch (err: any) {
        return Promise.reject(err);
      }
    },
  },
});
